

#import "BleTool.h"


@implementation BleTool{
    NSDate *_timeUpgradeBegin;
    
    NSArray <RTKOTAUpgradeBin*> *_images;
    NSArray <RTKOTAUpgradeBin*> *_imagesForPrimaryBud;
    NSArray <RTKOTAUpgradeBin*> *_imagesForSecondaryBud;
    BOOL _upgradeNextConnectedPeripheral;
    NSString *deviceName;
    NSString *filePath;
    RTKDFUTestModeFlag _testMode;

}

+(BleTool *)sharedManager
{
    static BleTool *sharedAccountManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedAccountManagerInstance = [[self alloc] init];
    });
    return sharedAccountManagerInstance;
}

- (void)initData{
    NSLog(@"BleTool-initData");
    self.OTAProfile = [[RTKOTAProfile alloc] init];
    self.OTAProfile.delegate = self;
}

- (void)setFilePath:(NSString *)path{
    NSLog(@"BleTool-setFilePath:%@",path);
    filePath = path;
}

- (void)setDeviceName:(NSString *)name{
    NSLog(@"BleTool-setDeviceName:%@",name);
    deviceName = name;
}

- (NSArray <RTKOTAUpgradeBin*> *)imagesUserSelected {
    NSLog(@"BleTool-imagesUserSelected");
    if (self.OTAPeripheral.isRWS) {
        return self.OTAPeripheral.budType == RTKOTAEarbudPrimary ? _imagesForPrimaryBud : _imagesForSecondaryBud;
    }
    return _images;
}

- (NSArray <RTKOTAUpgradeBin*> *)toUpgradeImages {
    NSLog(@"BleTool-toUpgradeImages");
    if (!self.OTAPeripheral)
        return nil;
    
    // 根据设备目前brank情况，过滤掉不符合的image
    switch (self.OTAPeripheral.activeBank) {
        case RTKOTABankTypeBank0:
            return [self.imagesUserSelected filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"upgradeBank=%d or upgradeBank=%d", RTKOTAUpgradeBank_Unknown, RTKOTAUpgradeBank_Bank1]];
        case RTKOTABankTypeBank1:
            return [self.imagesUserSelected filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"upgradeBank=%d or upgradeBank=%d", RTKOTAUpgradeBank_Unknown, RTKOTAUpgradeBank_SingleOrBank0]];
        default:
            return self.imagesUserSelected;
    }
}


- (void)setDFUPeripheral:(RTKMultiDFUPeripheral *)DFUPeripheral {
    NSLog(@"BleTool-setDFUPeripheral");
    DFUPeripheral.testFlag = _testMode;
    _DFUPeripheral = DFUPeripheral;
}

- (void)searchDevice:(NSString *)name{
    NSLog(@"searchDevice %@ %@",deviceName,self.OTAProfile);
    [self.OTAProfile scanForPeripherals];
}


- (void)MYPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"BleTool-MYPeripheral");
    [[self delegate] BleToolProgress:@"11,0"];
    NSLog(@"连接中...");
    if (self.OTAPeripheral) {
        [self.OTAProfile cancelConnectionWith:self.OTAPeripheral];
    }
    self.OTAPeripheral = [self.OTAProfile OTAPeripheralFromCBPeripheral:peripheral];
    [self.OTAProfile connectTo:self.OTAPeripheral];
}



-(void)onFileHasSelected:(NSString *)fileName
{
    NSLog(@"BleTool-onFileHasSelected");
    _imagesForPrimaryBud = nil;
    _imagesForSecondaryBud = nil;
    _images = nil;
    
    NSString *s = fileName;
    if (self.OTAPeripheral.isRWS) {
        NSArray <RTKOTAUpgradeBin*> *primaryBins, *secondaryBins;
        NSError *err = [RTKOTAUpgradeBin extractCombinePackFileWithFilePath:s toPrimaryBudBins:&primaryBins secondaryBudBins:&secondaryBins];
        if (!err) {
            _imagesForPrimaryBud = primaryBins;
            _imagesForSecondaryBud = secondaryBins;
            
            if (_imagesForPrimaryBud.count == 1 && !_imagesForPrimaryBud.lastObject.ICDetermined) {
                [_imagesForPrimaryBud.lastObject assertAvailableForPeripheral:self.OTAPeripheral];
            }
            if (_imagesForSecondaryBud.count == 1 && !_imagesForSecondaryBud.lastObject.ICDetermined) {
                [_imagesForSecondaryBud.lastObject assertAvailableForPeripheral:self.OTAPeripheral];
            }
        } else if (self.OTAPeripheral.notEngaged) {
            NSError *err;
            NSArray <RTKOTAUpgradeBin*> *extractedImages = [RTKOTAUpgradeBin imagesExtractedFromMPPackFilePath:s error:&err];
            if (extractedImages.count == 1 && !extractedImages.lastObject.ICDetermined) {
                [extractedImages.lastObject assertAvailableForPeripheral:self.OTAPeripheral];
            }
            if (!err) {
                self.OTAPeripheral.budType == RTKOTAEarbudSecondary ? (_imagesForSecondaryBud = extractedImages) : (_imagesForPrimaryBud = extractedImages);
            }
        }
    } else {
        NSError *error;
        _images = [RTKOTAUpgradeBin imagesExtractedFromMPPackFilePath:s error:&error];
        if (_images.count == 1 && !_images.lastObject.ICDetermined) {
            [_images.lastObject assertAvailableForPeripheral:self.OTAPeripheral];
        }
    }
    
    if (self.toUpgradeImages.count == 0) {
//        [SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"选择的文件无效或不匹配"]];
//        [SVProgressHUD dismissWithDelay:1.2];
//        NSLog(@"选择的文件无效或不匹配...🌟");
    } else if (self.OTAPeripheral.OTAVersion == 3) {
        // 非config image有更新版本可以进行升级
        BOOL haveImgNewer = NO;
        BOOL haveImgOlder = NO;
        for (RTKOTAUpgradeBin *toUpgradeImg in self.toUpgradeImages) {
            if (toUpgradeImg.type != RTKOTAImageType_BBpro_OTAHeader &&
                toUpgradeImg.type != RTKOTAImageType_BBpro_Secure_Boot_Loader &&
                toUpgradeImg.type != RTKOTAImageType_BBpro_ROM_PATCH &&
                toUpgradeImg.type != RTKOTAImageType_BBpro_APP_IMG &&
                toUpgradeImg.type != RTKOTAImageType_BBpro_DSP_System &&
                toUpgradeImg.type != RTKOTAImageType_BBpro_DSP_APP) {
                continue;
            }
            for (RTKOTABin *installedBin in self.OTAPeripheral.bins) {
                if (toUpgradeImg.type == installedBin.type) {
                    if (!haveImgNewer && [installedBin compareVersionWith:toUpgradeImg] == NSOrderedAscending)
                        haveImgNewer = YES;
                    if (!haveImgOlder && [installedBin compareVersionWith:toUpgradeImg] == NSOrderedDescending)
                        haveImgOlder = YES;
                }
            }
        }
        
        if (haveImgNewer && !haveImgOlder) {
            goto Completion;
        } else if (haveImgOlder) {
//            [SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"选择的文件无效或不匹配"]];
//            [SVProgressHUD dismissWithDelay:1.2];
//            NSLog(@"选择的文件无效或不匹配...🌟");
            
            _imagesForPrimaryBud = nil;
            _imagesForSecondaryBud = nil;
            _images = nil;
            
            goto Completion;
        }
        
        // 非config image没有更新版本，但config有更新版本可以升级
        BOOL haveConfigImgNewer = NO;
        BOOL haveConfigImgOlder = NO;
        for (RTKOTAUpgradeBin *toUpgradeImg in self.toUpgradeImages) {
            if (toUpgradeImg.type == RTKOTAImageType_BBpro_OTAHeader ||
                toUpgradeImg.type == RTKOTAImageType_BBpro_Secure_Boot_Loader ||
                toUpgradeImg.type == RTKOTAImageType_BBpro_ROM_PATCH ||
                toUpgradeImg.type == RTKOTAImageType_BBpro_APP_IMG ||
                toUpgradeImg.type == RTKOTAImageType_BBpro_DSP_System ||
                toUpgradeImg.type == RTKOTAImageType_BBpro_DSP_APP) {
                continue;
            }
            for (RTKOTABin *installedBin in self.OTAPeripheral.bins) {
                if (toUpgradeImg.type == installedBin.type) {
                    if (!haveConfigImgNewer && [installedBin compareVersionWith:toUpgradeImg] == NSOrderedAscending)
                        haveConfigImgNewer = YES;
                    if (!haveConfigImgOlder && [installedBin compareVersionWith:toUpgradeImg] == NSOrderedDescending)
                        haveConfigImgOlder = YES;
                }
            }
        }
        
        if (haveConfigImgNewer && !haveConfigImgOlder) {
            goto Completion;
        } else {
//            [SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"选择的文件无效或不匹配"]];
//            [SVProgressHUD dismissWithDelay:1.2];
            NSLog(@"选择的文件无效或不匹配...🌟");
            
            _imagesForPrimaryBud = nil;
            _imagesForSecondaryBud = nil;
            _images = nil;
            
            goto Completion;
        }
    }
 
    
Completion:
    NSLog(@"刷新...🌟");
    
   
}


- (void)removeLastSelectImages {
    _images = nil;
    _imagesForPrimaryBud = nil;
    _imagesForSecondaryBud = nil;
}

#pragma mark - RTKLEProfileDelegate

- (void)profileManagerDidUpdateState:(RTKLEProfile *)profile {
    NSLog(@"BleTool-profileManagerDidUpdateState: %@ %@",deviceName,self.OTAProfile);
    [self searchDevice:deviceName];
}

- (void)profile:(RTKLEProfile *)profile didDiscoverPeripheral:(RTKLEPeripheral *)peripheral{
    
    if(deviceName != nil &&  peripheral.name != nil){
        NSLog(@"BleTool-didDiscoverPeripheral:%@ flag:%d ",peripheral.name,[deviceName isEqualToString:peripheral.name]);
        if([deviceName isEqualToString:peripheral.name]){
            [[self delegate] BleToolProgress:@"1,0"];
            [self.OTAProfile stopScan];
            [self MYPeripheral:peripheral.CBPeripheral];
        }
    }
    
}

- (void)profile:(RTKLEProfile *)profile didConnectPeripheral:(nonnull RTKLEPeripheral *)peripheral {
    NSLog(@"BleTool-didConnectPeripheral: %@--%@ flag:%d",peripheral,self.OTAPeripheral,([peripheral isEqual:self.OTAPeripheral]));
    if ([peripheral isEqual:self.OTAPeripheral]) {
        _upgradeSilently = YES;
        _upgradeNextConnectedPeripheral = NO;
        [self onFileHasSelected:filePath];
        [self clickStart:100];
        [[self delegate] BleToolProgress:@"3,0"];
    } else if ([peripheral isEqual:self.DFUPeripheral]) {
        [self.DFUPeripheral upgradeImages:self.toUpgradeImages inOTAMode:!self.upgradeSilently];
        dispatch_async(dispatch_get_main_queue(), ^{
            self->_timeUpgradeBegin = [NSDate date];
            NSLog(@"Updating...");
        });
    }
}

- (void)profile:(RTKLEProfile *)profile didDisconnectPeripheral:(nonnull RTKLEPeripheral *)peripheral error:(nullable NSError *)error {
    [[self delegate] BleToolProgress:@"9,0"];
    NSLog(@"BleTool-didDisconnectPeripheral");
    if (peripheral == self.OTAPeripheral) {
        if (!error) {
            NSLog(@"重置连接");
            self.OTAPeripheral = nil;
        }
    }
}

- (void)profile:(RTKLEProfile *)profile didFailToConnectPeripheral:(RTKLEPeripheral *)peripheral error:(nullable NSError *)error {
    NSLog(@"BleTool-didFailToConnectPeripheral");
    [[self delegate] BleToolProgress:@"3,0"];
//    dispatch_async(dispatch_get_main_queue(), ^{
//        NSLog(@"连接外设失败");
//    });
}


#pragma mark - RTKMultiDFUPeripheralDelegate

- (void)DFUPeripheral:(RTKDFUPeripheral *)peripheral didSend:(NSUInteger)length totalToSend:(NSUInteger)totalLength {
    NSLog(@"BleTool-didSend");
    NSString *lv = [NSString stringWithFormat:@"%.0f",((((float)length)/totalLength) * 100)];
    NSLog(@"更新中。。。RTKMultiDFUPeripheralDelegate:%@",lv);
    [[self delegate] BleToolProgress:[NSString stringWithFormat:@"6,%@",lv]];
}

- (void)presentTransmissionSpeed {
    NSLog(@"BleTool-presentTransmissionSpeed");
    dispatch_async(dispatch_get_main_queue(), ^{
        NSUInteger lengthTotalImages = 0;
        for (RTKOTAUpgradeBin *bin in self.toUpgradeImages) {
            lengthTotalImages += bin.data.length;
        }
        NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:self->_timeUpgradeBegin];
        [[self delegate] BleToolProgress:@"8,0"];
    });
}

- (void)DFUPeripheral:(RTKDFUPeripheral *)peripheral didFinishWithError:(nullable NSError *)err {
    NSLog(@"BleTool-didFinishWithError");
    if (err) {
        _upgradeNextConnectedPeripheral = NO;
        NSLog(@"升级失败");
        [[self delegate] BleToolProgress:@"7,0"];
    } else {
        // 计算总传输速率
        [self presentTransmissionSpeed];
        if (self.upMis==100) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"FirmwareList_carryOut" object:self];
        }
       
        if (self.OTAPeripheral.isRWS && !self.OTAPeripheral.notEngaged && _upgradeNextConnectedPeripheral) {
            // 升级副耳外设
            [self.OTAProfile scanCompanionPeripheralOf:self.OTAPeripheral withCompletionHandler:^(BOOL success, NSError * _Nullable err, RTKOTAPeripheral * _Nullable targetPeripheral) {
                if (success) {
                    self.OTAPeripheral = targetPeripheral;
                    [self.OTAProfile connectTo:targetPeripheral];
                } else {
                    NSLog(@"无法连接另外一只外设");
                }
            }];
            
            [self.OTAProfile cancelConnectionWith:peripheral];
            [self.OTAProfile cancelConnectionWith:self.OTAPeripheral];
            
            self.DFUPeripheral = nil;
            self.OTAPeripheral = nil;
            
            return;
        }
    }
    
}

- (void)DFUPeripheral:(RTKMultiDFUPeripheral *)peripheral willUpgradeImage:(RTKOTAUpgradeBin *)image {
    NSLog(@"BleTool-willUpgradeImage");
}

- (void)DFUPeripheral:(RTKDFUPeripheral *)peripheral didSend:(NSUInteger)len ofImage:(RTKOTAUpgradeBin *)image {
    NSLog(@"BleTool-didSend");
}

- (void)DFUPeripheral:(RTKMultiDFUPeripheral *)peripheral didUpgradeImage:(RTKOTAUpgradeBin *)image {
    NSLog(@"BleTool-didUpgradeImage");
}

- (void)DFUPeripheral:(RTKMultiDFUPeripheral *)peripheral didActiveImages:(NSArray<RTKOTAUpgradeBin*>*)images {
    NSLog(@"BleTool-didActiveImages");
}

//升级按钮
- (void)clickStart:(NSInteger )upMisVC
{
    self.upMis = upMisVC;
    RTKLogDebug(@"[RTKOTA] 电量充足.");
    [self startOta];
}
#pragma mark - start ota
- (void)startOta
{
    NSLog(@"startOta-toUpgradeImages:%d",self.toUpgradeImages.count);
    if (self.toUpgradeImages.count > 0) {
        NSLog(@"startOta-OTAPeripheral.isRWS:%d",self.OTAPeripheral.isRWS);
        NSLog(@"startOta-OTAPeripheral.canEnterOTAMode:%d",self.OTAPeripheral.canEnterOTAMode);
        NSLog(@"startOta-OTAPeripheral.canUpgradeSliently:%d",self.OTAPeripheral.canUpgradeSliently);
        if (self.OTAPeripheral.isRWS) {
            _upgradeSilently = YES;
            if(!self.OTAPeripheral.notEngaged){
                _upgradeNextConnectedPeripheral = YES;
            }
            
            RTKDFUPeripheral *DFUPeripheral = [self.OTAProfile DFUPeripheralOfOTAPeripheral:self.OTAPeripheral];
            DFUPeripheral.delegate = self;
            [self.OTAProfile connectTo:DFUPeripheral];
            self.DFUPeripheral = (RTKMultiDFUPeripheral*)DFUPeripheral;
            NSLog(@"请稍后692");
//            [SVProgressHUD showWithStatus:@"请稍后"];
        }
//        else if (self.OTAPeripheral.canEnterOTAMode && self.OTAPeripheral.canUpgradeSliently) {
//
//        }
        else if (self.OTAPeripheral.canEnterOTAMode) {
            _upgradeSilently = NO;
            [[self delegate] BleToolProgress:@"4,0"];
            [self.OTAProfile translatePeripheral:self.OTAPeripheral toDFUPeripheralWithCompletion:^(BOOL success, NSError * _Nullable err, RTKDFUPeripheral * _Nullable peripheral) {
                if (success) {
                    [[self delegate] BleToolProgress:@"5,0"];
                    NSLog(@"连接OTA模式下的外设");
                    self.DFUPeripheral = (RTKMultiDFUPeripheral*)peripheral;
                    peripheral.delegate = self;
                    [self.OTAProfile connectTo:peripheral];
                } else {
                    NSLog(@"切换到OTA mode失败");
                }
            }];
        }
//        else if (self.OTAPeripheral.canUpgradeSliently) {
//            _upgradeSilently = YES;
//            RTKDFUPeripheral *DFUPeripheral = [self.OTAProfile DFUPeripheralOfOTAPeripheral:self.OTAPeripheral];
//            DFUPeripheral.delegate = self;
//            [self.OTAProfile connectTo:DFUPeripheral];
//            self.DFUPeripheral = (RTKMultiDFUPeripheral*)DFUPeripheral;
//        }
    }
    else {
        [[self delegate] BleToolProgress:@"12,0"];
    }
}



@end
